package DataServer

import (
	"fmt"
	"log"
	"strings"

	"gitee.com/dark.H/DataDash/in"
	"github.com/gorilla/websocket"
)

func NodeGroupBy(c *websocket.Conn, mt int, key string) {
	groups := make(map[string][]int)
	names := make(in.KeySet)
	options := make(in.G)
	for id, node := range NowPanelNodes {

		data1 := node["data"].(in.G)

		if v, ok := data1[key]; ok {
			groups[fmt.Sprint(v)] = append(groups[fmt.Sprint(v)], id)
			names[fmt.Sprint(v)] = true
		}
	}
	for name := range names {
		options[name] = in.G{
			"borderWidth": len(groups[name]),
		}
	}
	OperReply(c, mt, "groups", in.Datas{in.G{
		"groups":  groups,
		"options": options,
		"names":   names.SortedList(),
	}})
}

func NodeSimilary(c *websocket.Conn, mt int, id int32, keys ...string) {
	nodeid := int(id)
	if dataCentry, ok := NowPanelNodes[nodeid]; ok {
		dataIN := dataCentry["data"].(in.G)
		for id, node := range NowPanelNodes {
			if id == nodeid {
				continue
			}
			data1 := node["data"].(in.G)
			// canConnected := false
			if len(keys) == 0 {
				for key, v := range dataIN {
					if data1[key] == v {
						NowPanelEdge[id] = nodeid

						NowEdgeConnectValue[id] = map[int]string{
							nodeid: fmt.Sprint(v),
						}

						break
					}
				}
			} else {
				for _, key := range keys {
					v := dataIN[key]
					if data1[key] == v {
						NowPanelEdge[id] = nodeid
						break
					}
				}
			}

		}
		nodes := RenderFromNowPanel("")
		OperReply(c, mt, "edges", nodes)
	}
}

func SearchedDatasAddNodeView(datas in.Datas, clearOld bool) {
	if clearOld {
		NowPanelNodes = make(map[int]in.G)
		NowPanelEdge = make(map[int]int)
		NowEdgeConnectValue = make(map[int]map[int]string)
	}
	for _, D := range datas {
		NowPanelNodes[D["id"].(int)] = D
	}
}

func NodeConnectWith(c *websocket.Conn, mt int, key string) {

	datas := in.MemoryGet(in.MemLastInfo.LastCacheKey)
	allCount := len(datas)
	edgesData := datas.ConnectedWith(func(gf, gt in.G, same, connected bool) bool {
		if !same {
			data1 := gf["data"].(in.G)
			data2 := gt["data"].(in.G)
			if fmt.Sprint(data1[key]) == fmt.Sprint(data2[key]) && data1[key] != nil {
				gf["label"] = key + ":" + fmt.Sprint(data1[key])
				gt["label"] = key + ":" + fmt.Sprint(data2[key])

				return true
			} else {
				// in.ColorD(gf)
				// in.ColorD(gt)
			}
		}
		return false
	})
	// usedIds := make(map[int]bool)
	// for id, node := range NowPanelNodes {
	// 	usedIds[id] = true
	// 	data1, ok := node["data"].(in.G)
	// 	if !ok {
	// 		continue
	// 	}
	// 	for id2, node2 := range NowPanelNodes {
	// 		if id2 == id || usedIds[id2] {
	// 			continue
	// 		}

	// 		if data2, ok := node2["data"].(in.G); ok {
	// 			if fmt.Sprint(data2[key]) == fmt.Sprint(data1[key]) && data1[key] != nil {
	// 				NowPanelEdge[id] = id2
	// 				NowEdgeConnectValue[id] = map[int]string{
	// 					id2: fmt.Sprint(data1[key]),
	// 				}
	// 			}
	// 		}
	// 		// log.Println(data1[key], data2[key])

	// 	}
	// }
	// if len(NowPanelEdge) == 0 {
	// 	edges := RenderFromNowPanel(key)
	// 	OperReply(c, mt, "edges", edges)
	// } else {
	// 	edges := RenderFromNowPanel(key)
	// 	OperReply(c, mt, "edges", edges)
	// }
	in.ColorL(in.MemLastInfo.LastConnectStr+"/"+in.MemLastInfo.LastTbStr, allCount, len(edgesData))
	OperReply(c, mt, "edges", edgesData)
}

func NodeHierarchy(c *websocket.Conn, mt int, fr, to string) {
	// lastKey := in.ParsePath(in.MemLastInfo.LastConnectStr + "/" + in.MemLastInfo.LastTbStr)
	// keys := in.MemoryKeys()
	// _, key, _ := in.FlowFromList(keys...).Action()
	datas := in.MemoryGet(in.MemLastInfo.LastCacheKey)
	allCount := len(datas)

	edgesData := datas.ConnectedWith(func(fg, tg in.G, same, connected bool) bool {
		if !same && !connected {
			df := fg["data"].(in.G)[fr]
			dt := tg["data"].(in.G)[to]
			// log.Fatal(df, dt)
			if df != nil && dt != nil {
				if strings.Contains(fmt.Sprint(df), fmt.Sprint(dt)) {
					fg["label"] = strings.Join([]string{fr + ":" + df.(string), to + ":" + fg["data"].(in.G)[to].(string)}, "\n")

					tg["label"] = strings.Join([]string{fr + ":" + dt.(string), to + ":" + tg["data"].(in.G)[to].(string)}, "\n")
					return true
				}
			}
		}
		return false
	})
	in.ColorL(in.MemLastInfo.LastConnectStr+"/"+in.MemLastInfo.LastTbStr, allCount, len(edgesData))
	if tree, err := edgesData.TryToGetTree(); err != nil {
		log.Println("Node Hierarchy Error:", err)
	} else {
		in.ColorL("Top", tree.Top, "Nodes:", len(tree.Nodes))
		replyDatas := tree.Levels(DisplaySettings.PageLen)
		OperReply(c, mt, "edges", replyDatas)
	}

}

// func NodeHierarchy(c *websocket.Conn, mt int, fr, to string) {
// 	allCount := len(NowPanelNodes)
// 	bar := NewBar(int64(allCount * allCount))
// 	NowPanelEdge = make(in.Edges)

// 	var datas in.Datas

// 	for id, node := range NowPanelNodes {

// 		data1, ok := node["data"].(in.G)
// 		if !ok {
// 			continue
// 		}
// 		for id2, node2 := range NowPanelNodes {
// 			bar.Increment(1)
// 			if id2 == id {
// 				continue
// 			}

// 			if data2, ok := node2["data"].(in.G); ok {
// 				dt := data1[to]
// 				df := data2[fr]
// 				if df == nil || dt == nil {
// 					continue
// 				}
// 				if strings.Contains(fmt.Sprint(df), fmt.Sprint(dt)) {
// 					// usedIds[id] = true
// 					// usedIds[id2] = true
// 					NowPanelEdge[id2] = id
// 					NowEdgeConnectValue[id] = map[int]string{
// 						id2: fmt.Sprint(dt),
// 					}

// 					fromData := NowPanelNodes[id]
// 					toData := NowPanelNodes[id2]
// 					toData["x"] = rand.Float32() * float32(allCount)
// 					toData["y"] = rand.Float32() * float32(allCount)
// 					toData["label"] = fmt.Sprintf("%v:%v\n%v:%v\n%v:%v", "noid", id2, fr, data2[fr], to, data2[to])

// 					fromData["x"] = rand.Float32() * float32(allCount)
// 					fromData["y"] = rand.Float32() * float32(allCount)
// 					fromData["label"] = fmt.Sprintf("%v:%v\n%v:%v\n%v:%v", "noid", id, fr, data1[fr], to, data1[to])

// 					datas = append(datas, in.G{
// 						"from":  id,
// 						"to":    id2,
// 						"fromP": fromData,
// 						"toP":   toData,
// 						"label": fmt.Sprint(dt),
// 					})
// 					if bar.NowSize%100 == 0 {
// 						bar.Log("Dealing... wait:")
// 					}

// 				}
// 			}
// 			// log.Println(data1[key], data2[key])
// 		}
// 	}
// 	// for id := range usedIds {
// 	// 	selectedNodes = append(selectedNodes, NowPanelNodes[id])
// 	// }
// 	// edges := RenderOnlyEdges(NowPanelEdge, nodes)
// 	// OperReply(c, mt, "detail", selectedNodes)
// 	// time.Sleep(2 * time.Second)
// 	in.ColorL("Rendering...")
// 	OperReply(c, mt, "edges", datas)

// }
